package cn.lili.controller.order;

import cn.lili.common.aop.annotation.PreventDuplicateSubmissions;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.SceneEnums;
import cn.lili.common.utils.ResultUtil;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.order.order.entity.vo.TradeCashierParamVO;
import cn.lili.modules.order.payment.TradeCashier;
import cn.lili.modules.payment.client.PaymentClient;
import cn.lili.modules.payment.entity.dto.CashierParam;
import cn.lili.modules.payment.entity.dto.PayParam;
import cn.lili.modules.payment.entity.enums.PaymentClientEnum;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.modules.payment.entity.enums.PaymentSceneEnums;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.simpleframework.xml.core.Validate;
import org.springframework.web.bind.annotation.*;

/**
 * 交易收银台
 *
 * @author liushuai(liushuai711 @ gmail.com)
 * @version v4.0
 * @Description:
 * @since 2023/4/14 16:39
 */
@RestController
@RequestMapping("/trade/cashier")
@Api(tags = "订单收银台")
@RequiredArgsConstructor
@Validate
@Slf4j
public class TradeCashierController {

    private final PaymentClient paymentClient;


    private final TradeCashier tradeCashier;


    @PreventDuplicateSubmissions
    @ApiOperation(value = "线下收款")
    @ApiImplicitParam(name = "tradeSn", value = "交易编号", required = true, dataType = "String", paramType = "path")
    @PostMapping(value = "/offline/{tradeSn}")
    public ResultMessage<Object> payTrade(@PathVariable String tradeSn) {

        if (!UserContext.getCurrentUser().getScene().equals(SceneEnums.MANAGER)) {
            throw new ServiceException("非管理员不能操作");
        }

        paymentClient.generatePaymentForm(tradeCashier.generatePaymentParams(tradeSn, PaymentClientEnum.NATIVE, PaymentMethodEnum.BANK_TRANSFER));

        return ResultUtil.success();
    }


    @GetMapping(value = "/tradeDetail")
    @ApiOperation(value = "获取支付详情")
    public ResultMessage<Object> paymentParams(String sn, ClientTypeEnum clientType) {
        CashierParam cashierParam = paymentClient.base(clientType.name());
        TradeCashierParamVO tradeCashierParamVO = new TradeCashierParamVO(cashierParam);
        TradeCashierParamVO result = tradeCashier.handlerCashierParams(sn, tradeCashierParamVO);
        //当最近的一笔未支付的订单是，免税订单，只展示微信支付
        tradeCashier.filterSupport(result);
        return ResultUtil.data(result);
    }


    @ApiImplicitParams({
            @ApiImplicitParam(name = "paymentMethod", value = "支付方式", paramType = "path", allowableValues = "WECHAT,ALIPAY"),
            @ApiImplicitParam(name = "paymentClient", value = "调起方式", paramType = "path", allowableValues = "APP,NATIVE,JSAPI,H5,MP")
    })
    @GetMapping(value = "/pay/{paymentMethodEnums}/{paymentClientEnums}")
    @ApiOperation(value = "支付")
    public ResultMessage<Object> payment(@PathVariable String paymentMethodEnums, @PathVariable String paymentClientEnums, String sn) {
        PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(paymentMethodEnums);
        PaymentClientEnum paymentClientEnum = PaymentClientEnum.valueOf(paymentClientEnums);

        try {
            PayParam payParam = tradeCashier.generatePaymentParams(sn, paymentClientEnum, paymentMethodEnum);
            log.info("payParam----{}",payParam);
            return paymentClient.generatePaymentForm(payParam);
        } catch (ServiceException se) {
            log.info("支付异常", se);
            throw se;
        } catch (Exception e) {
            log.error("收银台支付错误", e);
            throw new ServiceException("收银台支付错误");
        }
    }


    @ApiImplicitParams({
            @ApiImplicitParam(name = "paymentMethod", value = "支付方式", paramType = "path", allowableValues = "WECHAT,ALIPAY"),
            @ApiImplicitParam(name = "paymentClient", value = "调起方式", paramType = "path", allowableValues = "APP,NATIVE,JSAPI,H5,MP"),
            @ApiImplicitParam(name = "paymentScene", value = "场景", paramType = "path", allowableValues = "VIP, AUDIT")
    })
    @GetMapping(value = "/paymentByScene/{paymentMethodEnums}/{paymentClientEnums}/{paymentSceneEnums}")
    @ApiOperation(value = "场景支付")
    public ResultMessage<Object> paymentByScene(@PathVariable String paymentMethodEnums, @PathVariable String paymentClientEnums,
                                                @PathVariable String paymentSceneEnums, String sn) {
        PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(paymentMethodEnums);
        PaymentClientEnum paymentClientEnum = PaymentClientEnum.valueOf(paymentClientEnums);
        PaymentSceneEnums paymentSceneEnum = PaymentSceneEnums.valueOf(paymentSceneEnums);
        try {
            return paymentClient.generatePaymentSceneForm(tradeCashier.generatePaymentBySceneParams(sn, paymentSceneEnum, paymentClientEnum, paymentMethodEnum));
        } catch (ServiceException se) {
            log.info("支付异常", se);
            throw se;
        } catch (Exception e) {
            log.error("收银台支付错误", e);
            throw new ServiceException("收银台支付错误");
        }
    }


}
